#include "qresourcetreewidget.h"

#include "qresourcelistwidget.h"

#include "qsoftcore.h"
#include "../sharedLib/qresourcemanager.h"

#include <QIcon>
#include <QPixmap>
#include <QHeaderView>
#include <QItemDelegate>
#include <QPalette>
#include <QPainter>
#include <QStyle>
#include <QMouseEvent>
#include <QListWidgetItem>

using namespace CORELIB;

static QIcon drawIndicatorIcon(const QPalette &palette,QStyle *style)
{
    QPixmap pix(14,14);

    pix.fill(Qt::transparent);

    QStyleOption branchOption;
    QRect r(QPoint(0,0),pix.size());
    branchOption.rect=QRect(2,2,9,9);
    branchOption.palette=palette;
    branchOption.state=QStyle::State_Children;

    QPainter p;
    p.begin(&pix);
    style->drawPrimitive(QStyle::PE_IndicatorBranch,&branchOption,&p);
    p.end();
    QIcon rc=pix;
    rc.addPixmap(pix,QIcon::Selected,QIcon::Off);
    branchOption.state |=QStyle::State_Open;

    pix.fill(Qt::transparent);
    p.begin(&pix);
    style->drawPrimitive(QStyle::PE_IndicatorBranch,&branchOption,&p);
    p.end();

    rc.addPixmap(pix,QIcon::Normal,QIcon::On);
    rc.addPixmap(pix,QIcon::Selected,QIcon::On);
    return rc;
}

namespace CORELIB
{

    class QResourceDelegate: public QItemDelegate
    {
    public :
        QResourceDelegate(QResourceTreeWidget* tree):m_tree(tree){}
        void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
        QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
    protected:
        QResourceTreeWidget *m_tree;
    };

}

void QResourceDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QTreeWidgetItem *item=m_tree->itemFromIndex(index);
    QStyleOptionViewItemV3 opt=option;
    if(m_tree->m_items.values().contains(item))
    {
        QColor c=opt.palette.color(QPalette::Dark);
        opt.palette.setColor(QPalette::Text,opt.palette.color(QPalette::BrightText));
        painter->fillRect(option.rect,c);
    }
    opt.state &=~ QStyle::State_HasFocus;
    QItemDelegate::paint(painter,opt,index);
}

QSize QResourceDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QSize sz=QItemDelegate::sizeHint(option,index);
    QTreeWidgetItem *item=m_tree->itemFromIndex(index);
    if(m_tree->m_items.values().contains(item))
    {
        sz.setHeight(21);
    }
    return sz;
}

QResourceTreeWidget::QResourceTreeWidget(QWidget *parent) :
    QTreeWidget(parent),
    m_select(NULL)
{
    setFocusPolicy(Qt::NoFocus);
    setFrameStyle(QFrame::NoFrame);
    setIndentation(0);
    setRootIsDecorated(false);
    setColumnCount(1);
    header()->hide();
    header()->setResizeMode(QHeaderView::Stretch);
    setTextElideMode(Qt::ElideMiddle);
    setVerticalScrollMode(ScrollPerPixel);
    setItemDelegate(new QResourceDelegate(this));

    m_icon=drawIndicatorIcon(this->palette(),this->style());

    SHAREDLIB::QResourceManager* manager=QSoftCore::getCore()->resourceManager();
    connect(manager,SIGNAL(resourceAdd(QString,QString)),this,SLOT(add(QString,QString)));

    QStringList firstList=manager->resourceFirstNames();
    foreach(const QString &first,firstList)
    {
        QStringList lastList=manager->resourceLastNames(first);
        foreach(const QString &last,lastList)
        {
            add(first,last);
        }
    }


    QPalette p=this->palette();
    p.setColor(QPalette::Inactive,QPalette::Highlight,p.color(QPalette::Active,QPalette::Highlight));
    p.setColor(QPalette::Inactive,QPalette::HighlightedText,p.color(QPalette::Active,QPalette::HighlightedText));
    this->setPalette(p);

}

void QResourceTreeWidget::add(const QString &firstName, const QString &lastName)
{

    SHAREDLIB::QResourceManager* manager=QSoftCore::getCore()->resourceManager();

    QByteArray data=manager->resourceData(firstName,lastName);
    if(data.size()==0)
    {
        return;
    }

    QPixmap p;
    p.loadFromData(data);

    QTreeWidgetItem *item=m_items.value(firstName);


    if(item==NULL)
    {
        item=new QTreeWidgetItem(this);
        item->setIcon(0,m_icon);
        item->setText(0,firstName);
        QTreeWidgetItem *sub=new QTreeWidgetItem(item);
        QResourceListWidget *wid=new QResourceListWidget;
        connect(wid,SIGNAL(itemClicked(QListWidgetItem*)),this,SLOT(select(QListWidgetItem*)));
        connect(wid,SIGNAL(itemDoubleClicked(QListWidgetItem*)),this,SLOT(doubleSelect(QListWidgetItem*)));
        setItemWidget(sub,0,wid);

        m_items.insert(firstName,item);
        m_widgets.insert(firstName,wid);
        m_widgetToItem.insert(wid,sub);
    }

    QResourceListWidget *wid=m_widgets.value(firstName);
    if(wid!=NULL)
    {
        wid->add(lastName,QIcon(p));
    }
    item->setExpanded(true);
    calcSize();
}

void QResourceTreeWidget::mousePressEvent(QMouseEvent *event)
{
    QTreeWidget::mousePressEvent(event);

    QTreeWidgetItem *item=itemAt(event->pos());

    if(item)
    {
        if(m_items.values().contains(item))
        {
            if(event->pos().x()+header()->offset()<20)
            {
                item->setExpanded(!item->isExpanded());
            }
        }
    }
}

void QResourceTreeWidget::resizeEvent(QResizeEvent *event)
{
    QTreeWidget::resizeEvent(event);
    calcSize();
}

void QResourceTreeWidget::calcSize()
{
    QMapIterator<QString,QResourceListWidget*>  it(m_widgets);
    while(it.hasNext())
    {
        it.next();
        it.value()->setFixedWidth(header()->width());
        it.value()->doItemsLayout();
        const int height = qMax(it.value()->ContentsSize().height() ,1);
        it.value()->setFixedHeight(height);
        m_widgetToItem.value(it.value())->setSizeHint(0,QSize(-1,height-1));
    }
}

void QResourceTreeWidget::select(QListWidgetItem *item)
{
    if(m_select==item)
    {
        return;
    }
    if(m_select!=NULL)
    {
        m_select->setSelected(false);
    }
    m_select=item;
    if(m_select!=NULL)
    {
        m_select->setSelected(true);
    }
    QResourceListWidget* wid=(QResourceListWidget*)sender();

    QMapIterator<QString,QResourceListWidget*>  it(m_widgets);

    QString firstName,lastName;

    while(it.hasNext())
    {
        it.next();
        if(it.value()==wid)
        {
            firstName=it.key();
            break;
        }
    }

    lastName=wid->getName(item);

    emit selectChanged(firstName,lastName);
}

void QResourceTreeWidget::doubleSelect(QListWidgetItem *item)
{
    QResourceListWidget* wid=(QResourceListWidget*)sender();

    QMapIterator<QString,QResourceListWidget*>  it(m_widgets);

    QString firstName,lastName;

    while(it.hasNext())
    {
        it.next();
        if(it.value()==wid)
        {
            firstName=it.key();
            break;
        }
    }

    lastName=wid->getName(item);

    emit doubleClick(firstName,lastName);
}

void QResourceTreeWidget::getSelectResource(QString &firstName, QString &lastName)
{

    QMapIterator<QString,QResourceListWidget*>  it(m_widgets);

    QString str;
    while(it.hasNext())
    {
        it.next();
        str=it.value()->getName(m_select);
        if(str!="")
        {
            firstName=it.key();
            lastName=str;
            break;
        }
    }

}
